package com.itheima.health.filter;



import com.alibaba.fastjson.JSON;
import com.itheima.health.annotation.MyAnno;
import com.itheima.health.common.MessageConst;

import com.itheima.health.controller.admin.*;
import com.itheima.health.dao.UserDao;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@WebFilter("/*")
@Component
public class LoginFilter implements Filter {
    @Autowired
    UserDao userDao;

    @SneakyThrows
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setContentType("application/json;charset=utf-8");

        //1. 获取本次请求的目标资源路径。如果是登录，就直接放行不拦截
        String uri = request.getRequestURI();
        String[] split = uri.split("/");
        if (split[1].equals("mobile")||"/user/getUsername".equals(uri)){
            filterChain.doFilter(servletRequest, servletResponse);
        }
        String funname = uri.substring(uri.lastIndexOf("/") + 1);
        if ("/user/login".equals(uri)) {
            log.info("本次请求是登录，直接放行");
            filterChain.doFilter(request, response);
            return;
        }
        HttpSession session = request.getSession();
        String userId = session.getAttribute("userId").toString();
        if (userId == null || "".equals(userId)) {
            log.warn("本次请求{}，没有携带userId，不允许访问", uri);
            response.setStatus(401);
            response.getWriter().println(JSON.toJSONString(MessageConst.NOT_LOGIN));
            return;
        }

        //根据用户查询角色表
        //3. 根据权限放行
        //通过反射获取每一个controller的所有方法
        Class<CheckItemController> controllerClass = CheckItemController.class;
        Method[] checkItemMethods = controllerClass.getMethods();
        execute(checkItemMethods,funname,userId,request,response,filterChain);

        Class<CheckGroupController> checkGroupControllerClass = CheckGroupController.class;
        Method[] checkGroupMethods = checkGroupControllerClass.getMethods();
        execute(checkGroupMethods,funname,userId,request,response,filterChain);

        Class<SetMealController> setMealControllerClass = SetMealController.class;
        Method[] setMealMethods = setMealControllerClass.getMethods();
        execute(setMealMethods,funname,userId,request,response,filterChain);

        Class<OrdersettingController> ordersettingControllerClass = OrdersettingController.class;
        Method[] ordersettingMethods = ordersettingControllerClass.getMethods();
        execute(ordersettingMethods,funname,userId,request,response,filterChain);

        Class<ReportController> reportControllerClass = ReportController.class;
        Method[] reportControllerMethods = reportControllerClass.getMethods();
        execute(reportControllerMethods,funname,userId,request,response,filterChain);

    }
    public void execute(Method[] methods,String funname,String userId,HttpServletRequest request,HttpServletResponse response,FilterChain filterChain) throws ServletException, IOException {
        List<Method> collect = Arrays.stream(methods).filter(f -> f.getName().equals(funname)).collect(Collectors.toList());
        if (collect.size() > 0){
            //获取用户所有的权限
            List<String> permissionList = userDao.getPermission(userId);
            MyAnno myAnno = collect.get(0).getAnnotation(MyAnno.class);
            if (myAnno != null){
                String empower = myAnno.empower();
                if (permissionList.contains(empower)){
                    // 只有在确认有权限后才放行
                    filterChain.doFilter(request, response);
                }else {
                    response.getWriter().println("没有权限");
                }
            }
        }
    }
}
